home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / copydsk.zip / COPYDISK.C < prev    next >
C/C++ Source or Header  |  1990-03-12  |  15KB  |  504 lines

  1. /*******************************************************************************
  2. *  Program:    COPYDISK.C  C 5.1 and MASM 5.1
  3. *
  4. *  Purpose:    Copies volume label, subdirectory structure and all files
  5. *           regardless of attribute type from one disk medium to another.
  6. *
  7. *  Author:        Gordon Harris
  8. *            3349 Humboldt Ave S
  9. *            Minneapolis, MN 55408
  10. *
  11. *            Comments can be addressed to my
  12. *            CompuSurve address: [72611,620]
  13. *
  14. *
  15. *
  16. * Description: COPYDISK is an XCOPY like utility which allows you to copy
  17. *           an entire disk to a drive of differing type, e.g. copy
  18. *           the contents of a 1.2 m floppy to a 1.44 m floppy, etc.
  19. *
  20. *           Unlike XCOPY, COPYDISK will copy the volume label from the
  21. *           source disk to the target, as well as copying all
  22. *           subdirectories and files including hidden, system or read-
  23. *           only files and directories.  All files on the target disk
  24. *           created by COPYDISK will have identical attributes (dates,
  25. *           times, etc) as the files on the source disk.  If the
  26. *           source disk is bootable, so will the resulting target disk.
  27. *
  28. *  Syntax:     The syntax for using COPYDISK is:
  29. *
  30. *           COPYDISK sourcedrive: targetdrive: [-n] [-x] [-f]
  31. *
  32. *           where "sourcedrive:" and "targetdrive:" are valid dos drives
  33. *           and [-n], [-x] and [-f] are optional parameters.
  34. *
  35. *  Operation:  Given valid parameters, COPYDISK (1) performs a media check
  36. *           on the indicated drives, (2) prompts the user for permission
  37. *           to delete all existing data from the target drive, (3) copies
  38. *           the volume label from the source drive to the target and then
  39. *           (4) proceeds to copy all files and directories from the source
  40. *           to the target.
  41. *
  42. *           COPYDISK will abort if its check of the media type of the
  43. *           target disk reveals that it is a fixed disk.  This protects
  44. *           you from inadvertently deleting the contents of a hard disk
  45. *           either by using an incorrect parameter for the target drive
  46. *           or by using a virtual drive name created by ASSIGN or SUBST
  47. *           which represents a fixed disk drive or subdirectory on a
  48. *           hard disk.
  49. *
  50. *           During the media check, COPYDISK installs its own critical
  51. *           error handler.  If a error is detected reading either the
  52. *           source or target drives, COPYDISK will prompt you to retry
  53. *           access to the disk.  If you choose not to retry access to
  54. *           the target disk, COPYDISK will prompt you as to whether you
  55. *           wish to format the target.
  56. *
  57. *           COPYDISK will also abort if the data on the source disk is
  58. *           too large to fit on the empty target disk, or if any errors
  59. *           occur reading data from the source or writing data to the
  60. *           target disks.
  61. *
  62. *  Optional Parameters:
  63. *        -n (no prompt).  This is useful when using COPYDISK in batch
  64. *           files.  With the "-n" parameter, COPYDISK will not prompt you
  65. *           for permission to delete all data from the target disk.
  66. *
  67. *        -x (relaxed media checking).  With this parameter, the target
  68. *           disk may be a hard disk and the source data may be larger
  69. *           than the capacity of the target disk.
  70. *
  71. *        -f (format target automatically if media check failure).  With
  72. *           this parameter, the DOS FORMAT.COM command will be spawned
  73. *           without prompting if the target disk fails the media check.
  74. *
  75. *  Credits:    Ray Duncan, Advanced MS DOS Programming, 1988, Microsoft Press
  76. *           Kevin P. Welch, "WFINDER"
  77. *
  78. *
  79. ********************************************************************************/
  80. #include <dos.h>
  81. #include <stdio.h>
  82. #include <stdlib.h>
  83. #include <fcntl.h>
  84. #include <errno.h>
  85. #include <malloc.h>
  86. #include <process.h>
  87. #include "COPYDISK.h"
  88.  
  89. char        *pSource;
  90. size_t        nBufSize;
  91. int        errno;
  92. int        nNumFiles;
  93. char        szSyntaxMsg [] = "Syntax: COPYDISK sourcedrive: targetdrive: -NoPrompt \n\n",
  94.         szMsg[80] = "\n";
  95.  
  96. union REGS inregs, outregs;
  97. struct SREGS segregs;
  98. unsigned _osversion;
  99.  
  100. main(int argc, char * argv[] )
  101.    {
  102.    int        bPrompt, bCheck, bFormat, n;
  103.    struct   drvinfo_t drv1, drv2;
  104.    int        crterror = 0;
  105.    char     szDrive1 [10], szDrive2 [10];
  106.  
  107.    errno = EINVAL;
  108.  
  109.    strcpy (szDrive1, " :\\*.*");
  110.    strcpy (szDrive2, " :");
  111.    if (argc < 3)
  112.       ErrExit("");
  113.    szDrive1 [0] = toupper(*argv [1]);
  114.    szDrive2 [0] = toupper(*argv [2]);
  115.  
  116.    /* check for same source & target drives */
  117.    if (szDrive1 [0] == szDrive2 [0])
  118.       ErrExit("Sourcedrive = Targetdrive");
  119.  
  120.    /* check remaining parameters */
  121.    bPrompt = TRUE;
  122.    bCheck  = TRUE;
  123.    bFormat = FALSE;
  124.    for (n = 3; n < argc; n++)
  125.       {
  126.       if (argv [n] [0] == '-' || argv [n] [0] == '/')
  127.      switch ( toupper(argv [n] [1]) )
  128.         {
  129.         case 'N':
  130.            bPrompt = FALSE;
  131.            break;
  132.         case 'X':
  133.            bCheck = FALSE;
  134.            break;
  135.         case 'F':
  136.            bFormat = TRUE;
  137.         }
  138.       }
  139.  
  140.    /* install critical error handler */
  141.    setint24 (&crterror);
  142.  
  143.    /* perform media check on source drive */
  144.    while ( !drvinfo(szDrive1 [0] - '@', &drv1))
  145.       {
  146.       if (!crterror)
  147.      {
  148.      sprintf (szMsg, "Source drive %c: not valid", *szDrive1);
  149.      ErrExit (szMsg);
  150.      }
  151.       crterror = 0;
  152.       printf("\r\7Error reading source disk %c:  Retry? (Y/N)  \b", *szDrive1);
  153.       if (toupper (getche()) != 'Y')
  154.      ErrExit ("");
  155.       }
  156.  
  157.    /* perform media check on target drive */
  158.    while ( !drvinfo(szDrive2 [0] - '@', &drv2))
  159.       {
  160.       if (!crterror)
  161.      {
  162.      sprintf (szMsg, "Target drive %c: not valid", *szDrive2);
  163.      ErrExit (szMsg);
  164.      }
  165.  
  166.       if (!bFormat)
  167.      {
  168.      printf("\r\7Error reading target disk %c:  Retry? (Y/N)  \b", *szDrive2);
  169.      if (toupper (getche()) == 'Y')
  170.         continue;
  171.      printf ("\rDo you wish to format disk in drive %c: ? (Y/N) ",*szDrive2);
  172.      bFormat = (toupper (getche()) == 'Y');
  173.      }
  174.  
  175.       if (crterror && bFormat)
  176.      {
  177.      switch (LOBYTE(_osversion))
  178.         {
  179.         case 3:
  180.            strcpy(szMsg, "/H");
  181.            break;
  182.         case 4:
  183.            strcpy(szMsg, "/AUTOTEST");
  184.            break;
  185.         default:
  186.            szMsg[0] = '\0';
  187.         }
  188.      printf("\rFormatting %s                                     \n", szDrive2);
  189.      spawnlp(P_WAIT,"format.com", "format.com", szDrive2, szMsg, NULL);
  190.      }
  191.       else
  192.      {
  193.      ErrExit("");
  194.      }
  195.       crterror = 0;
  196.       bFormat = FALSE;
  197.       }
  198.  
  199.    /* de-install critical error handler here */
  200.    restint24 ();
  201.  
  202.    /* check results of previous media check */
  203.    if (bCheck)
  204.       {
  205.       if (drv2.type == 0x0f8)
  206.      {
  207.      errno = EACCES;
  208.      sprintf(szMsg, "Targetdrive %c: is a fixed disk", *szDrive2);
  209.      ErrExit(szMsg);
  210.      }
  211.  
  212.       if (drv1.lDataSize > drv2.lDiskSpace)
  213.      {
  214.      sprintf (szMsg, "Source drive %c: data too large for target drive %c",
  215.               *szDrive1, *szDrive2);
  216.      ErrExit(szMsg);
  217.      }
  218.       }
  219.  
  220.    if (bPrompt)
  221.       {
  222.       printf ("\rWARNING: all data on drive %c will be deleted.  Do you wish to continue? (Y/N) ", *szDrive2);
  223.       if (toupper (getche()) != 'Y')
  224.      exit(1);
  225.       }
  226.  
  227.    volcopy (szDrive1[0] - '@', szDrive2 [0] - '@');
  228.  
  229.    printf ("\rDeleting files and directories on drive %c:"
  230.        "                                     \r", *szDrive2);
  231.    strcat (szDrive2, "\\");
  232.    chdir (szDrive2);
  233.    strcat (szDrive2, "*.*");
  234.    DelAll(szDrive2, _A_NORMAL | _A_RDONLY | _A_HIDDEN | _A_SYSTEM);
  235.  
  236.    /* Allocate file buffer */
  237.    nBufSize = _memmax();
  238.    pSource = malloc (nBufSize);
  239.  
  240.    if (pSource == NULL)
  241.       {
  242.       ErrExit ("Insufficient memory available");
  243.       }
  244.  
  245.    nNumFiles = 0;
  246.    szDrive1 [2] = '\0';
  247.    szDrive2 [2] = '\0';
  248.    printf ("Copying files and directories from drive %c: to %c:\n%s\\\n", *szDrive1, *szDrive2, szDrive2);
  249.    strcat (szDrive1, "\\*.*");
  250.    strcat (szDrive2, "\\*.*");
  251.    CopyAll(szDrive1, szDrive2, _A_NORMAL | _A_RDONLY | _A_HIDDEN | _A_SYSTEM);
  252.    free(pSource);
  253.    printf(" %d file(s) copied                            \n", nNumFiles);
  254.    }
  255.  
  256. void ErrExit (char *msg)
  257.    {
  258.    fprintf(stderr, "\nError %d--%s%s", errno, _strerror(msg), szSyn